package hxy.bytecode.jdk;

/**
 * https://blog.csdn.net/xigua355/article/details/84768468
 *
 * @author houxiaoyi
 */
public class GcTest {
    /**
     * 在localvarGc1()中，在申请空间后，立即进行垃圾回收，很明显，由于byte数组被变量a引用，因此无法回收这块空间。
     */
    public void localvarGc1() {
        byte[] a = new byte[6 * 1024 * 1024];
        System.gc();
    }

    /**
     * 在localvarGc2()中，在垃圾回收前，先将变量a置为null，使byte数组失去强引用，故垃圾回收可以顺利回收byte数组。
     */
    public void localvarGc2() {
        byte[] a = new byte[6 * 1024 * 1024];
        a = null;
        System.gc();
    }

    /**
     * 对于localvarGc3()，在进行垃圾回收前，先使局部变量a失效，虽然变量a已经离开了作用域，
     * 但是变量a依然存在于局部变量表中，并且也指向这块byte数组，故byte数组依然无法被回收。
     */
    public void localvarGc3() {
        {
            byte[] a = new byte[6 * 1024 * 1024];
        }
        System.gc();
        int b =0;
    }

    /**
     * 这个是最难理解的了
     * 对于localvarGc4()，在垃圾回收之前，不仅使变量a失效，更是申明了变量c，使变量c复用了变量a之前的栈，由于变量a此时被销毁，故垃圾回收器可以顺利回收byte数组。
     * https://blog.csdn.net/gotobat/article/details/83512673
     */
    public void localvarGc4() {
        {
            byte[] a = new byte[6 * 1024 * 1024];
        }
        int c = 10;
        System.gc();
    }

    /**
     * 对于localvarGc5()，它首先调用了localvarGc1()，很明显，在localvarGc1()中并没有释放byte数组，
     * 但在localvarGc1()返回后，它的栈帧被销毁，自然也包含了栈帧中的所有局部变量，
     * 故byte数组失去引用，在localvarGc5()的垃圾回收中被回收。
     */
    public void localvarGc5() {
        localvarGc1();
        System.gc();
    }

    public static void main(String[] args) {

        GcTest ins = new GcTest();

        ins.localvarGc3();
        ins.localvarGc4();

    }
}